#include "debug.h"
#include "OLED.h"
#include "oledfont.h"

void SDA_In(void)
{
	static GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure);
}

void SDA_Out(void)
{
	static GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure);
}

void I2C_GPIO_CONFIG(void)
{
	static GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

//SCL
	GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(I2C_SCL_PORT, &GPIO_InitStructure);
//SDA
	GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(I2C_SDA_PORT, &GPIO_InitStructure);
//OLED_RESET
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void I2C_Start(void)
{
	SDA_Out();
	I2C_SDA_1
	;
	I2C_SCL_1
	;
	Delay_Us(5);
	I2C_SDA_0
	;
	Delay_Us(5);
	I2C_SCL_0
	;
}

void I2C_Stop(void)
{
	SDA_Out();
	I2C_SDA_0
	;
	I2C_SCL_0
	;
	I2C_SCL_1
	;
	Delay_Us(5);
	I2C_SDA_1
	;
	Delay_Us(5);
}

void I2C_Ack(void)
{
	SDA_Out();
	I2C_SDA_0
	;
	I2C_SCL_1
	;
	Delay_Us(5);
	I2C_SCL_0
	;
}

void I2C_NoAck(void)
{
	SDA_Out();
	I2C_SDA_1
	;
	I2C_SCL_1
	;
	Delay_Us(5);
	I2C_SCL_0
	;
}

u8 I2C_WaitAck(void)
{
	u8 i;
	SDA_Out();
	I2C_SDA_0
	;
	I2C_SCL_0
	;
	SDA_In();

	for (i = 0; i < I2C_ACK_TRIES; i++)
	{
		if (I2C_SDA_R() == 0)
		{
			i = 0;
			break;
		}
	}
	I2C_SCL_1
	;
	Delay_Us(5);
	I2C_SCL_0
	;
	return i;
}

void I2C_SendByte(u8 dat)
{
	u8 i;
	SDA_Out();
	for (i = 0; i < 8; i++)
	{
		if (dat & 0X80)
		{
			I2C_SDA_1
			;
		}
		else
		{
			I2C_SDA_0
			;
		}
		I2C_SCL_1
		;
		Delay_Us(5);
		I2C_SCL_0
		;
		Delay_Us(5);
		dat <<= 1;
	}
//    I2C_SDA_1;Delay_Us(5);

	I2C_SCL_1
	;
	Delay_Us(5);
	I2C_SCL_0
	;
	Delay_Us(5);
//    return I2C_WaitAck();
}

/**********************************************
 // IIC Write Command
 **********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
	I2C_Start();
	I2C_SendByte(0x78);            //Slave address,SA0=0
	I2C_SendByte(0x00);          //write command
	I2C_SendByte(IIC_Command);
	I2C_Stop();
}
/**********************************************
 // IIC Write Data
 **********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
	I2C_Start();
	I2C_SendByte(0x78);
	I2C_SendByte(0x40);          //write data
	I2C_SendByte(IIC_Data);
	I2C_Stop();
}

void OLED_WR_Byte(unsigned dat, unsigned cmd)
{
	if (cmd)
	{
		Write_IIC_Data(dat);
	}
	else
	{
		Write_IIC_Command(dat);
	}
}

void OLED_Set_Pos(unsigned char x, unsigned char y)
{
	OLED_WR_Byte(0xb0 + y, OLED_CMD);
	OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);
	OLED_WR_Byte((x & 0x0f), OLED_CMD);
}

void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDCÃüÁî
	OLED_WR_Byte(0X14, OLED_CMD);  //DCDC ON
	OLED_WR_Byte(0XAF, OLED_CMD);  //DISPLAY ON
}

void OLED_Display_Off(void)
{
	OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDCÃüÁî
	OLED_WR_Byte(0X10, OLED_CMD);  //DCDC OFF
	OLED_WR_Byte(0XAE, OLED_CMD);  //DISPLAY OFF
}

void OLED_Clear(void)
{
	u8 i, n;
	for (i = 0; i < 8; i++)
	{
		OLED_WR_Byte(0xb0 + i, OLED_CMD);
		OLED_WR_Byte(0x00, OLED_CMD);
		OLED_WR_Byte(0x10, OLED_CMD);
		for (n = 0; n < 128; n++)
			OLED_WR_Byte(0, OLED_DATA);
	}
}
void OLED_On(void)
{
	u8 i, n;
	for (i = 0; i < 8; i++)
	{
		OLED_WR_Byte(0xb0 + i, OLED_CMD);
		OLED_WR_Byte(0x00, OLED_CMD);
		OLED_WR_Byte(0x10, OLED_CMD);
		for (n = 0; n < 128; n++)
			OLED_WR_Byte(1, OLED_DATA);
	}
}

void OLED_ShowChar(u8 x, u8 y, char chr, u8 Char_Size)
{
	unsigned char c = 0, i = 0;
	c = chr - ' ';
	if (x > Max_Column - 1)
	{
		x = 0;
		y = y + 2;
	}
	if (Char_Size == FONT_16)
	{
		OLED_Set_Pos(x, y);
		for (i = 0; i < 8; i++)
		{
			OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);
		}
		OLED_Set_Pos(x, y + 1);
		for (i = 0; i < 8; i++)
		{
			OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);
		}
	}
	else
	{
		OLED_Set_Pos(x, y);
		for (i = 0; i < 6; i++)
		{
			OLED_WR_Byte(F6x8[c][i], OLED_DATA);
		}
	}
}

u32 oled_pow(u8 m, u8 n)
{
	u32 result = 1;
	while(n--)result*=m;
	return result;
}

void OLED_ShowNum(u8 x, u8 y, u32 num, u8 len, u8 size2)
{
	u8 t, temp;
	u8 enshow = 0;
	for (t = 0; t < len; t++)
	{
		temp = (num / oled_pow(10, len - t - 1)) % 10;
		if (enshow == 0 && t < (len - 1))
		{
			if (temp == 0)
			{
				OLED_ShowChar(x + (size2 / 2) * t, y, ' ', size2);
				continue;
			}
			else
			{
				enshow = 1;
			}
		}
		OLED_ShowChar(x + (size2 / 2) * t, y, temp + '0', size2);
	}
}

void OLED_ShowString(u8 x, u8 y, char *chr, u8 Char_Size)
{
	unsigned char j = 0;
	while (chr[j]!='\0')
	{
		OLED_ShowChar(x,y,chr[j],Char_Size);
		x+=8;
		if(x>120)
		{
			x=0;y+=2;
		}
		j++;
	}
}

void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char BMP[])
{
	unsigned int j = 0;
	unsigned char x, y;

	if (y1 % 8 == 0)
		y = y1 / 8;
	else
		y = y1 / 8 + 1;
	for (y = y0; y < y1; y++)
	{
		OLED_Set_Pos(x0, y);
		for (x = x0; x < x1; x++)
		{
			OLED_WR_Byte(BMP[j++], OLED_DATA);
		}
	}
}

/***********************Initial code*********************/
void OLED_Init(void)
{

	I2C_GPIO_CONFIG();
	OLED_RESET_L;
	Delay_Ms(100);
	OLED_RESET_H;
	Delay_Ms(100);
	OLED_WR_Byte(0xAE, OLED_CMD);  //¹Ø±ÕÏÔÊ¾

	OLED_WR_Byte(0x40, OLED_CMD);  //---set low column address
	OLED_WR_Byte(0xB0, OLED_CMD);  //---set high column address

	OLED_WR_Byte(0xC8, OLED_CMD);  //-not offset

	OLED_WR_Byte(0x81, OLED_CMD);  //ÉèÖÃ¶Ô±È¶È
	OLED_WR_Byte(0xff, OLED_CMD);

	OLED_WR_Byte(0xa1, OLED_CMD);  //¶ÎÖØ¶¨ÏòÉèÖÃ

	OLED_WR_Byte(0xa6, OLED_CMD);  //

	OLED_WR_Byte(0xa8, OLED_CMD);  //ÉèÖÃÇý¶¯Â·Êý
	OLED_WR_Byte(0x1f, OLED_CMD);

	OLED_WR_Byte(0xd3, OLED_CMD);
	OLED_WR_Byte(0x00, OLED_CMD);

	OLED_WR_Byte(0xd5, OLED_CMD);
	OLED_WR_Byte(0xf0, OLED_CMD);

	OLED_WR_Byte(0xd9, OLED_CMD);
	OLED_WR_Byte(0x22, OLED_CMD);

	OLED_WR_Byte(0xda, OLED_CMD);
	OLED_WR_Byte(0x02, OLED_CMD);

	OLED_WR_Byte(0xdb, OLED_CMD);
	OLED_WR_Byte(0x49, OLED_CMD);

	OLED_WR_Byte(0x8d, OLED_CMD);
	OLED_WR_Byte(0x14, OLED_CMD);

	OLED_WR_Byte(0xaf, OLED_CMD);
	OLED_Clear();
}

void OLED_ShowBar(u8 BarLen)
{

	//OLED_Set_Pos(x, y);
	u8 line_up,x;

	//u8 line_down;
	if (BarLen == 0)
	{
		line_up = 0;
	//	line_down = 0;
	}
	else
	{
		line_up = 1 + (BarLen - 1) / 2;
//		line_down = 127+BarLen / 2;
	}
	OLED_Set_Pos(0, 0);
	for (x = 0; x < 128; x++)
	{
		if ( line_up> x)
		{
			OLED_WR_Byte(0xFF, OLED_DATA);
		}
		else
		{
			OLED_WR_Byte(0x00, OLED_DATA);
		}
	}
/*	OLED_Set_Pos(0, 1);
	for (x = 0; x < 128; x++)
	{
		if (line_down > x)
		{
			OLED_WR_Byte(0x0F, OLED_DATA);
		}
		else
		{
			OLED_WR_Byte(0x00, OLED_DATA);
		}
	}
*/
}

